﻿using Admin.NET.Core;
using Furion.DatabaseAccessor;
using Furion.DatabaseAccessor.Extensions;
using Furion.DependencyInjection;
using Furion.DynamicApiController;
using Furion.FriendlyException;
using Mapster;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace Admin.NET.Application
{
    /// <summary>
    /// 计划管理
    /// </summary>
    [Route("api/planmanager")]
    [ApiDescriptionSettings("道路巡检", Name = "PlanManager", Order = 100)]
    [AllowAnonymous]
    public class PlanService : IDynamicApiController, IPlanService, IScoped
    {
        /// <summary>
        /// 添加巡检计划
        /// </summary>
        /// <param name="plan"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public async Task<object> PostPlan(PlanInfoDto plan)
        {
            var en = Db.GetRepository<PlanInfo>().FirstOrDefault(s => s.PlanName == plan.PlanName, false);
            if (en != null)
                throw Oops.Oh("计划名称已存在，请重新输入！");
            PlanInfo planInfo = plan.Adapt<PlanInfo>();
            planInfo.PlanType = "计划";
            planInfo.PlanStatus = "待检";
            Db.GetRepository<PlanInfo>().InsertNow(planInfo);
            return "添加成功";
        }
        /// <summary>
        /// 巡检车 添加巡检计划
        /// </summary>
        /// <param name="plan"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public async Task<object> PostCarPlan(PlanInfoDto plan)
        {
            var en = Db.GetRepository<PlanInfo>().FirstOrDefault(s => s.PlanName == plan.PlanName, false);
            if (en != null)
                throw Oops.Oh("计划名称已存在，请重新输入！");
            PlanInfo planInfo = plan.Adapt<PlanInfo>();
            planInfo.PlanType = "实时";
            planInfo.PlanStatus = "已检";
            planInfo.CarryDt = DateTime.Now;
            var ent = Db.GetRepository<PlanInfo>().InsertNow(planInfo);
            return ent.Entity.Id;
        }


        /// <summary>
        /// 修改巡检计划
        /// </summary>
        /// <param name="plan"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public async Task<object> PostPlanEdit(PlanInfoDto plan)
        {
            PlanInfo planInfo = plan.Adapt<PlanInfo>();
            var en = Db.GetRepository<PlanInfo>().FirstOrDefault(s => s.PlanName == plan.PlanName && s.Id != planInfo.Id, false);
            if (en != null)
                throw Oops.Oh("计划名称已存在，请重新输入！");
            Db.GetRepository<PlanInfo>().UpdateInclude(planInfo, new[] { nameof(PlanInfo.PlanName)
                    , nameof(PlanInfo.PlanGPS)
                    ,nameof(PlanInfo.CarId)
                    , nameof(PlanInfo.PlanDt) });
            return "修改成功";
        }

        /// <summary>
        /// 巡检车 修改巡检计划
        /// </summary>
        /// <param name="plan"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public async Task<object> PostCarPlanEdit(PlanInfoDto plan)
        {
            PlanInfo planInfo = plan.Adapt<PlanInfo>();
            planInfo.PlanStatus = "已检";
            planInfo.CarryDt = DateTime.Now;
            Db.GetRepository<PlanInfo>().UpdateInclude(planInfo, new[] {
                    nameof(PlanInfo.PlanName)
                    , nameof(PlanInfo.PlanStatus)
                    , nameof(PlanInfo.CarId)
                    , nameof(PlanInfo.CarryDt) });
            return "修改成功";
        }


        /// <summary>
        /// 添加或修改巡检计划
        /// </summary>
        /// <param name="plan"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public async Task<object> PostPlanAddorEdit(PlanInfoDto plan)
        {
            PlanInfo planInfo = Db.GetRepository<PlanInfo>().FirstOrDefault(x => x.Id == plan.Id, tracking: false);
            if (planInfo != null)
            {
                return await PostPlanEdit(plan);
            }
            else
            {
                return await PostPlan(plan);
            }

        }

        /// <summary>
        /// 删除巡检计划
        /// </summary>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public async Task<object> GetPlanDel([FromQuery] long planId)
        {
            Db.GetRepository<PlanInfo>().DeleteNow(planId);
            return "删除成功";
        }

        /// <summary>
        /// 获取计划列表
        /// </summary>
        /// <param name="dateTime"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public async Task<object> GetPlanList([FromQuery] long CarId, [FromQuery] string PlanDt)
        {
            List<PlanInfoDto> list = Db.GetRepository<PlanInfo>().Where(plan => plan.CarId == CarId && plan.PlanDt == DateTime.Parse(PlanDt)).Adapt<List<PlanInfoDto>>();
            return list;
        }


        /// <summary>
        /// 获取所有计划列表
        /// </summary>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public async Task<object> GetPlanListAll()
        {
            var list = (from p in Db.GetRepository<PlanInfo>().AsQueryable()
                       join d in Db.GetRepository<CarInfo>().AsQueryable() on p.CarId equals d.Id into results
                       from d in results.DefaultIfEmpty()
                       orderby p.CreatedTime descending
                       select new PlanInfoDto
                       {
                           Id = p.Id,
                           CarId = p.CarId,
                           CarNum = d.CarNum,
                           CarryDt = p.CarryDt,
                           CarryDtStr = p.CarryDt.ToString("yyyy-MM-dd"),
                           PlanDt = p.PlanDt,
                           CreatedTime = p.CreatedTime ?? new DateTimeOffset(),
                           PlanDtStr = p.PlanDt.ToString("yyyy-MM-dd"),
                           PlanGPS = p.PlanGPS,
                           PlanName = p.PlanName,
                           PlanStatus = p.PlanStatus,
                           PlanType = p.PlanType,
                           ScoreId = p.ScoreId,
                           ScoreNum = p.ScoreNum ?? "-",
                       }).ToList();
            var gpslist = Db.GetRepository<Plan_GPS>().AsQueryable().GroupBy(g => g.PlanId).Select(g => new
            {
                PlanId = g.Key,
                Count = g.Count(),
            });
            foreach (var item in list)
            {
                item.CarryGPS = gpslist.Where(s => s.PlanId == item.Id && s.Count > 0).Count() > 0 ? "true" : "false";
            }
            return list;
        }



        /// <summary>
        /// 获取待检计划列表
        /// </summary>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public async Task<object> GetIsCarryPlanList()
        {
            List<PlanInfoDto> list = Db.GetRepository<PlanInfo>().Where(plan => plan.PlanStatus == "待检").Adapt<List<PlanInfoDto>>();
            return list;
        }

        /// <summary>
        /// 获取计划日期列表
        /// </summary>
        /// <param name="CarId"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public async Task<object> GetPlanDateList([FromQuery] long CarId)
        {
            List<PlanInfoDto> list = $"select CONVERT(varchar(100), PlanDt, 23) PlanDtStr from planinfo where carid='{CarId}' GROUP BY CONVERT(varchar(100), PlanDt, 23)".SqlQuery<PlanInfoDto>().ToList();
            return list;
        }


        /// <summary>
        /// 获取计划巡检GPS轨迹与目标信息
        /// </summary>
        /// <param name="PlanId"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public async Task<object> GetPlanGPSInfo([FromQuery] long PlanId)
        {
            string sql = $"select t.Id,t.CarId,PlanName,PlanGPS,PlanType,c.carnum,PlanStatus" +
                $",CONVERT(varchar(100), PlanDt, 23) PlanDtStr" +
                $",CONVERT(varchar(100), CarryDt, 23) CarryDtStr" +
                $",'['+stuff((select ',['+GPS+']' from IT_Plan_GPS where PlanId=t.id FOR xml PATH('')), 1, 1, '')+']' as CarryGPS" +
                $" from IT_Plan_Info t left join IT_CarInfo c on t.CarId=c.id where t.id={PlanId}";
            PlanInfoDto list = sql.SqlQuery<PlanInfoDto>().FirstOrDefault();
            if (list != null)
            {
                list.TargetList = Db.GetRepository<Plan_Target>().Where(s => s.PlanId == PlanId).Adapt<List<TargetListDto>>();
                list.PlanTaskRecordList = (from t in Db.GetRepository<Plan_Task>().AsQueryable()
                                           join r in Db.GetRepository<Plan_Task_Record>().AsQueryable()
                                           on t.Id equals r.PlanTaskId into rt
                                           from r in rt.DefaultIfEmpty()
                                           where t.PlandId == PlanId
                                           select r).Adapt<List<PlanTaskRecordListDto>>();
                foreach (var item in list.TargetList)
                {
                    item.IMG = qiniuHelper.GetImg(item.IMG);
                }
            }
            return list;
        }
    }
}
